package com.tracking.application.activities;

import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.*;
import android.content.res.Resources;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import android.widget.AdapterView.OnItemSelectedListener;
import com.followme.module.common.*;
import com.google.android.gms.maps.GoogleMap;
import com.tracking.application.DataBase.DbAdapter;
import com.tracking.application.R;
import com.tracking.application.fragments.HistoryFragment;
import com.tracking.application.fragments.StartFragment;
import com.tracking.application.listeners.ActionBarTabListener;
import com.tracking.application.util.CommonModuleApp;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Kamil.O
 * Description: Main activity in application
 * Date: 18.11.13
 * Time: 20:28
 */
public class MainApplicationActivity extends Activity {
    public GpsTrackerService gpsTrackerService;
    public LocationManager locationManager;
    public PendingIntent pendingIntent;
    private GpsTrackerBroadcastReceiver gpsTrackerBroadcastReceiver = new GpsTrackerBroadcastReceiver();
    private boolean isRecording = false;

    protected long SECOND_UPDATE = 7;
    protected long MIN_DISTANCE_CHANGE_FOR_UPDATES = 2; // 2 meters
    protected long MIN_TIME_BW_UPDATES = 1000 * SECOND_UPDATE * 1; // 10 seconds

    protected boolean isGPSEnabled = false;
    protected boolean isSateliteEnabled = false;
    protected boolean isNetworkEnabled = false;

    protected int m1;
    protected int m2;
    protected int al;

    private ImageButton imgButtonPlay;
    private ImageButton imgButtonStop;
    private ImageButton imgButtonMap;

    private double firstLatitude;
    private double firstLongitude;
    private double firstAltitude;

    private int mapMode = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initializeActionBarTabs();
        ReceiverManager.registerBroadcatReceiver(this, CommonModuleApp.KEY_INTENT_ACTION_GPS_TO_MAIN_APP, broadcastReceiver);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //---use the LocationManager class to obtain locations data---
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        Intent intent= new Intent(this, GpsTrackerService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        DbSqlLiteUtil dbSqlLiteUtil = new DbSqlLiteUtil();

        try {
            dbSqlLiteUtil.copyDbFromAssets(getPackageName(), DbAdapter.DATABASE_NAME, getBaseContext().getAssets().open(DbAdapter.DATABASE_NAME));
        } catch (IOException e) {
            e.printStackTrace();
        }

        setSpinnersListeners();
        findImageButtonsReferences();
        showSearchSatelite(CommonModuleApp.KEY_SEARCH_NO);
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (locationManager != null) locationManager.removeUpdates(pendingIntent);
        gpsTrackerService.stopSelf();
        unbindService(mConnection);
        unregisterReceiver(broadcastReceiver);
        finish();
    }

    protected BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(CommonModuleApp.KEY_INTENT_ACTION_GPS_TO_MAIN_APP)){
                Bundle bundle = intent.getExtras();
                firstLatitude = (Double) bundle.get(CommonModuleApp.KEY_GPS_LAT);
                firstLongitude = (Double) bundle.get(CommonModuleApp.KEY_GPS_LONG);
                firstAltitude = (Double) bundle.get(CommonModuleApp.KEY_GPS_ALTITUDE);

                String actionSearch = (String) bundle.get(CommonModuleApp.KEY_SEARCH_SATELITE);
                showSearchSatelite(actionSearch);
            }
        }
    };

    public void showSearchSatelite(String actionSearch) {
        ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
        TextView sateliteText = (TextView) findViewById(R.id.sateliteText);

        if (actionSearch.equals(CommonModuleApp.KEY_SEARCH_SEARCH)){
            sateliteSearch(progressBar, sateliteText);
        }else if(actionSearch.equals(CommonModuleApp.KEY_SEARCH_FIND)){
            isSateliteEnabled = true;
            sateliteFind(progressBar, sateliteText);
        }else if (actionSearch.equals(CommonModuleApp.KEY_SEARCH_NO)){
            if (isGPSEnabled && !isRecording){
                if (progressBar != null) progressBar.setVisibility(View.VISIBLE);
                if (sateliteText != null) sateliteText.setVisibility(View.VISIBLE);
            }
        }
    }

    public void checkSatelite(){
        ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
        TextView sateliteText = (TextView) findViewById(R.id.sateliteText);

        if (isGPSEnabled && isSateliteEnabled){
            sateliteFind(progressBar, sateliteText);
        }else if (isGPSEnabled && !isSateliteEnabled){
            sateliteSearch(progressBar, sateliteText);
        }
    }

    private void sateliteSearch(ProgressBar progressBar, TextView sateliteText) {
        if (progressBar != null) progressBar.setVisibility(View.VISIBLE);
        if (sateliteText != null) {
            sateliteText.setVisibility(View.VISIBLE);
            sateliteText.setText(R.string.search_signal);
        }
    }

    private void sateliteFind(ProgressBar progressBar, TextView sateliteText) {
        if (progressBar != null) progressBar.setVisibility(View.GONE);
        if (sateliteText != null) {
            sateliteText.setVisibility(View.VISIBLE);
            sateliteText.setText(R.string.fins_satelite);
        }
    }

    private void findImageButtonsReferences() {
        imgButtonPlay = (ImageButton) findViewById(R.id.image_button_play);
        imgButtonStop = (ImageButton) findViewById(R.id.image_button_stop);
        imgButtonMap = (ImageButton) findViewById(R.id.image_button_map);
    }

    private void setSpinnersListeners(){
        Spinner spinner1 = (Spinner) findViewById(R.id.spinnerMonitoring1);
        Spinner spinner2 = (Spinner) findViewById(R.id.spinnerMonitoring2);
        Spinner spinner3 = (Spinner) findViewById(R.id.spinnerAlgorithm);

        if (spinner1 != null) spinner1.setOnItemSelectedListener(new Monitoring1Listener());
        if (spinner2 != null) spinner2.setOnItemSelectedListener(new Monitoring2Listener());
        if (spinner3 != null) spinner3.setOnItemSelectedListener(new AlgorithmListener());
    }

    private ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className, IBinder binder) {
            GpsTrackerService.MyBinder b = (GpsTrackerService.MyBinder) binder;
            gpsTrackerService = b.getService();
            Log.d(CommonModuleApp.TAG_LOG_CAT, "onServiceConnected");
            startService();
            startBroadCastReceiver();
        }

        public void onServiceDisconnected(ComponentName className) {
            gpsTrackerService = null;
        }
    };

    private void startBroadCastReceiver() {
        Intent i = new Intent(this, GpsTrackerBroadcastReceiver.class);
        i.setAction(LocationManager.KEY_LOCATION_CHANGED);
        pendingIntent = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

        //---request for location updates using GPS---
        locationManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER,
                MIN_TIME_BW_UPDATES,
                MIN_DISTANCE_CHANGE_FOR_UPDATES,
                pendingIntent);
    }

    private void startService(){
        Log.d(CommonModuleApp.TAG_LOG_CAT, "startService GpsTrackerService");
        Intent service = new Intent(this, GpsTrackerService.class);
        this.startService(service);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public void onBackPressed() {
        Log.d("CDA", "onBackPressed Called");

        if (isRecording){
            AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
            alertDialog.setTitle(R.string.attention);
            alertDialog.setMessage(R.string.confirm_stop_recording);

            alertDialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,int which) {
                    possitiveStopRecording();
                    dialog.cancel();
                    closeApp();
                }
            });

            alertDialog.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

            alertDialog.show();
        }else{
            closeApp();
        }
    }

    private void closeApp() {
        Intent setIntent = new Intent(Intent.ACTION_MAIN);
        setIntent.addCategory(Intent.CATEGORY_HOME);
        setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(setIntent);
        finish();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.language:
                showDialogRadio();
                return true;
            case R.id.modemap:
                showDialogMapMode();
                return true;
            case R.id.exit:
                Log.d(CommonModuleApp.TAG_LOG_CAT, "Close app FollowMe");
                finish();
                return true;
            case R.id.db:
                Log.d(CommonModuleApp.TAG_LOG_CAT, "DB export / Delete");
                Intent myIntent = new Intent(this, ExportDbActivity.class);
                this.startActivity(myIntent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void showDialogMapMode() {
        Resources res = getResources();

        final CharSequence[] stringArray = res.getStringArray(R.array.map_mode_array);
        AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
        alt_bld.setTitle(R.string.map_mode);
        alt_bld.setSingleChoiceItems(stringArray, -1, new DialogInterface

            .OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                switch (item) {
                    case 0:
                        mapMode = GoogleMap.MAP_TYPE_NORMAL;
                        break;
                    case 1:
                        mapMode = GoogleMap.MAP_TYPE_TERRAIN;
                        break;
                    case 2:
                        mapMode = GoogleMap.MAP_TYPE_SATELLITE;
                        break;
                }
                dialog.cancel();
            }
        });

        AlertDialog alert = alt_bld.create();
        alert.show();
    }

    private void showDialogRadio() {
        Resources res = getResources();

        final CharSequence[] stringArray = res.getStringArray(R.array.language_array);
        AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
        alt_bld.setTitle(R.string.select_language);
        alt_bld.setSingleChoiceItems(stringArray, -1, new DialogInterface

            .OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                String lang = null;
                if (item == 0) lang = "pl";
                if (item == 1) lang = "en";

                Localization.setLanguage(getBaseContext(), lang, getApplicationContext());

                Intent intent = getIntent();
                finish();
                startActivity(intent);
            }
        });
        AlertDialog alert = alt_bld.create();
        alert.show();
    }

    public void startRecordingRoad(View view){
        locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled) {
            CommonModuleUtil.showDialogAlert(this,
                    getString(R.string.gps_disable),
                    getString(R.string.gps_disable_content),
                    getString(R.string.settings_gps),
                    getString(R.string.cancel_gps),
                    Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        }else {
            if (isSateliteEnabled){
                if (!isRecording) {
                    EditText editText = (EditText) findViewById(R.id.title_tracking);
                    gpsTrackerService.registerReceiverFromGpsToService(editText.getText().toString(), this);
                }

                setButtonSecondState();

                Intent intent = new Intent(this, TabsActivity.class);
                intent.putExtra(CommonModuleApp.KEY_ID_ROUTE, gpsTrackerService.getIdRoad());
                intent.putExtra(CommonModuleApp.KEY_GPS_LAT, firstLatitude);
                intent.putExtra(CommonModuleApp.KEY_GPS_LONG, firstLongitude);
                intent.putExtra(CommonModuleApp.KEY_GPS_ALTITUDE, firstAltitude);
                intent.putExtra(CommonModuleApp.KEY_MAP_MODE, mapMode);
                intent.putExtra(CommonModuleApp.KEY_TYPE_REDIRECT, "PLAY");
                isRecording = true;
                startActivity(intent);

            }else {

                AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
                alertDialog.setTitle(R.string.attention);
                alertDialog.setMessage(R.string.no_find_satelite);

                alertDialog.setNegativeButton(R.string.cancel_gps, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

                alertDialog.show();
            }
        }
    }

    public void stopRecording(View view){
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
        alertDialog.setTitle(R.string.attention);
        alertDialog.setMessage(R.string.confirm_stop_recording);

        alertDialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                possitiveStopRecording();
                dialog.cancel();
            }
        });

        alertDialog.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        alertDialog.show();
    }

    private void possitiveStopRecording() {
        gpsTrackerService.updateEndDateRecording();
        gpsTrackerService.unregisteredReceiverFromGpsToService();
        setButtonsFirstState();

        this.firstLatitude = -1;
        this.firstLongitude = -1;

        this.isSateliteEnabled = false;
        this.isRecording = false;
    }

    public void choiseStateButtons(){
        if (isRecording) {
            setButtonSecondState();
        }else {
            setButtonsFirstState();
        }
    }

    private void setButtonsFirstState() {
        findImageButtonsReferences();

        imgButtonPlay.setVisibility(View.VISIBLE);
        imgButtonStop.setVisibility(View.GONE);
        imgButtonMap.setVisibility(View.GONE);
    }

    private void setButtonSecondState() {
        findImageButtonsReferences();

        imgButtonPlay.setVisibility(View.GONE);
        imgButtonStop.setVisibility(View.VISIBLE);
        imgButtonMap.setVisibility(View.VISIBLE);
    }

    public void showMapRecording(View view){
        Intent intent = new Intent(this, TabsActivity.class);
        intent.putExtra(CommonModuleApp.KEY_ID_ROUTE, gpsTrackerService.getIdRoad());
        intent.putExtra(CommonModuleApp.KEY_GPS_LAT, firstLatitude);
        intent.putExtra(CommonModuleApp.KEY_GPS_LONG, firstLongitude);
        intent.putExtra(CommonModuleApp.KEY_MAP_MODE, mapMode);
        intent.putExtra(CommonModuleApp.KEY_TYPE_REDIRECT, "SHOW_MAP");
        startActivity(intent);
        isRecording = true;
    }

    private void initializeActionBarTabs(){
        ActionBar actionBar = getActionBar();
        actionBar.removeAllTabs();

        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        ActionBar.Tab tab = actionBar
                .newTab()
                .setText(R.string.start)
                .setTabListener(new ActionBarTabListener<StartFragment>(this, "START", StartFragment.class));
        actionBar.addTab(tab);

        tab = actionBar
                .newTab()
                .setText(R.string.history)
                .setTabListener(new ActionBarTabListener<HistoryFragment>(this, "HISTORY", HistoryFragment.class));
        actionBar.addTab(tab);
    }

    /*
    * First spinner listener
    * */
    public class Monitoring1Listener implements OnItemSelectedListener {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            m1 = position;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {}
    }

    /*
    * Second spinner listener
    * */
    public class Monitoring2Listener implements OnItemSelectedListener  {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            m2 = position;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {}
    }

    /*
    * Third spinner listener
    * */
    public class AlgorithmListener implements OnItemSelectedListener  {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            switch (position){
                case 0:
                    SECOND_UPDATE = 7;
                    break;
                case 1:
                    SECOND_UPDATE = 5;
                    break;
                case 2:
                    SECOND_UPDATE = 3;
                    break;
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {}
    }

    public int getMapMode() {
        return mapMode;
    }

    public void setMapMode(int mapMode) {
        this.mapMode = mapMode;
    }
}
